var private const	Mode_pos = 1;
var private	change_flag = OFF;

function InputPlane;
function private PolyInterpolation;

function private ModeChange()
{
	draw_mode = !draw_mode;
	change_flag = ON;
//	if( draw_mode == ON )
//		Status_title[Mode_pos] = "断面: 表示";
//	else
//		Status_title[Mode_pos] = "断面:非表示";
//	DrawStatus();
}

//
//	面を分割する
// sel: 処理する面を示すセレクトクラス
// pos[3]: 平面を表す頂点配列
// obj1, obj2: 分割後のポリゴンが属するオブジェクト番号
//
function ZantePolygons( sel, pos, obj1, obj2 )
{
	var mat1;
	var i, vers, orgsel;
	var z[MAXVERTEX];
	var atemp[3];
	var temp;
	var type;
	var flagp, flagm;
	var flag;
	var p1, p2;

	mat1 = move(UNIT_MATRIX, pos[0] * (-1)) / vec(UNIT_MATRIX,
				pos[1]-pos[0], (pos[1]-pos[0]) * (pos[2]-pos[0]));

	orgsel  = Select();
	Select(sel);

	while (PolyLoad()) {
		vers = PolyVertexs();
		flagp = TRUE;
		flagm = TRUE;
		for (i = 0; i < vers; i++) {
			element(Position(PolyGetVertex(i))*mat1, atemp);
			z[i] = atemp[2];
			if (z[i] < 0) {
				flagp = FALSE;
			}
			if (z[i] > 0) {
				flagm = FALSE;
			}
		}
		z[vers] = z[0];
		if (flagp) {
			PolyObj(obj1);
			PolyAppend();
		} else if (flagm) {
			PolyObj(obj2);
			PolyAppend();
		} else {
			flagp = FALSE;
			if (z[0] > 0) {
				flagp = TRUE;
				for (i = 0; i < vers+1; i++) {
					z[i] = -z[i];
				}
			}
			flag = 0;
			p1 = -1;
			p2 = -1;
			for (i = 0; i < vers; i++) {
				if (z[i+1] > 0) {
					p1 = i;
					if (z[i] < 0) {
						PolyInterpolation(i, -(0.0+z[i]) / (z[i+1] - z[i]));
						flag++;
						i++;
						p1++;
					}
					break;
				}
			}
			for (; i < vers; i++) {
				if (z[i+1] < 0) {
					p2 = i + flag;
					if (z[i] > 0) {
						PolyInterpolation(i+flag, -(0.0+z[i]) / (z[i+1] - z[i]));
						flag++;
						i++;
						p2++;
					}
					break;
				}
			}
			vers += flag;
			if (p1 >= 0 & p2 >= 0) {

//print("\nvers=", vers, ", p1=", p1, ", p2=", p2, "PolyVertexs=", PolyVertexs(), "\n");
				PolyShiftVertex(p1);
				if (flagp) {
					PolyObj(obj2);
				} else {
					PolyObj(obj1);
				}
				PolyVertexs(p2-p1+1);
				PolyAppend();

				PolyVertexs(vers);
				PolyShiftVertex(p2-p1);
				if (flagp) {
					PolyObj(obj1);
				} else {
					PolyObj(obj2);
				}
				PolyVertexs(vers-(p2-p1)+1);
				PolyAppend();
			}
//			PolySave();
		}
	}

	Select(orgsel);
}
function private PolyInterpolation(inspos, rate)
{
	var v1, v2, ver;
	var pos, vec, u, v;
	var uv1[2], uv2[2];
	v1 = PolyGetVertex(inspos);
	if (inspos < PolyVertexs() - 1) {
		v2 = PolyGetVertex(inspos+1);
	} else {
		v2 = PolyGetVertex(0);
	}
	pos = Position(v1) * (1.0-rate) + Position(v2) * rate;
	if (PolyType() == POLY_SHADE | PolyType() == POLY_UVSHADE) {
		vec = Vector(v1) * (1.0-rate) + Vector(v2) * rate;
	} else {
		vec = vector(1,1,1);
	}
	if (PolyType() == POLY_UV | PolyType() == POLY_UVSHADE) {
		Mapping(v1, uv1);
		Mapping(v2, uv2);
		u = (0.0+uv1[0]) * (1.0-rate) + (0.0+uv2[0]) * rate;
		v = (0.0+uv1[1]) * (1.0-rate) + (0.0+uv2[1]) * rate;
	} else {
		u = 0;
		v = 0;
	}
	ver = Vertex(pos, vec, u, v);
//print("\n",inspos, "\nv1=", v1, "\nv2=", v2, "\nvr=", ver);
	PolyInsVertex(ver, inspos+1);
}

function ZanteEdge( sel, pos )
{
	var edge;
	edge = Edge();

	var mat1;
	var i, vers, orgsel;
	var z[MAXVERTEX];
	var atemp[3];
	var temp;
	var type;
	var flagp, flagm;
	var rate;
	var p1, p2;
	var v1, v2;

	mat1 = move(UNIT_MATRIX, pos[0] * (-1)) / vec(UNIT_MATRIX,
				pos[1]-pos[0], (pos[1]-pos[0]) * (pos[2]-pos[0]));

	orgsel  = Select();
	Select(sel);

	while (PolyLoad()) {
		vers = PolyVertexs();
		flagp = TRUE;
		flagm = TRUE;
		PolySetVertex(PolyGetVertex(0), vers);
		for (i = 0; i < vers; i++) {
			element(Position(PolyGetVertex(i))*mat1, atemp);
			z[i] = atemp[2];
			if (z[i] < 0) {
				flagp = FALSE;
			}
			if (z[i] > 0) {
				flagm = FALSE;
			}
		}
		z[vers] = z[0];
		z[vers+1] = z[1];
		if (flagp != TRUE & flagm != TRUE) {
			if (z[0] > 0) {
				for (i = 0; i < vers+1; i++) {
					z[i] = -z[i];
				}
			}
			p1 = -1;
			p2 = -1;
			for (i = 0; i < vers; i++) {
				if (z[i+1] > 0) {
					if (z[i] < 0) {
						v1 = PolyGetVertex(i);
						v2 = PolyGetVertex(i+1);
						rate = -(0.0+z[i]) / (z[i+1] - z[i]);
						p1 = Vertex(Position(v1) * (1.0-rate) + Position(v2) * rate);
					} else {
						p1 = PolyGetVertex(i);
					}
					break;
				}
			}
			for (; i < vers+1; i++) {
				if (z[i+1] < 0) {
					if (z[i] > 0) {
						v1 = PolyGetVertex(i);
						v2 = PolyGetVertex(i+1);
						rate = -(0.0+z[i]) / (z[i+1] - z[i]);
						p2 = Vertex(Position(v1) * (1.0-rate) + Position(v2) * rate);
					} else {
						p2 = PolyGetVertex(i);
					}
					break;
				}
			}
			if (i == vers+1) {
				continue;
			}
			edge = edge + Edge(p1, p2);
		}
	}

	Select(orgsel);
	return edge;
}

function _Zante()
{
	var	const	org_obj_num = "_zan";
	var	obj_num[2], temp;
	var	vers, i, j, k;
	var	point[3], pos[3];
	var	key, prev_sel, work_sel, sel;
	var	edge, edge_temp;
	var	pick, draw_flag = ON;

	draw_mode = OFF;
	change_flag = OFF;
	prev_sel = Select();
	if( SelectPolygons() == 0 )
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg3 );
		return;
	}
	work_sel = Select();
	Select( prev_sel );

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"断面表示	C",	ModeChange,CheckMode,
			"--------",		SEPARATE_MENU,
			"切断中止	ESC",	MenuQuit
		), Menu_Title );
	ClearStatus();
	Status_title[0] = "【面切断中】";
//	if( draw_mode == ON )
//		Status_title[Mode_pos] = "断面: 表示";
//	else
//		Status_title[Mode_pos] = "断面:非表示";
	DrawStatus();

	quit_flag = FALSE;

	cur = Cursor();
	pick = cur;
	point[0] = cur;
	pos[0] = Position( point[0] );
	vers = 1;
	edge = Edge();
	input_flag = OFF;
	while( TRUE )
	{
		if( draw_flag == ON )
		{
			DrawLine( cur, point[vers-1] );
			if(( draw_mode == ON ) & ( vers == 2 ))
				DrawEdge(edge);
		}
		key = WaitEvent();
		if( key )
			input_flag = ON;
		if(( ShiftStat() & 1 ) == 1 )
		{
			cur = Cursor();
			TrimCursor(point[vers-1], MouseWindow());
			Cursor( cur );
		}
		else
			cur = Cursor();
		key = KeyCode();
		if ( input_flag | key == INPUT_KEY )
		{
			if( vers == 1 )
			{
				if( cur == point[0] )
				{
					Warning();
					if( novice_flag == ON )
						Message( "最初に指定した点と同じ点です\n"
							+"別の点を指定してください" );
				}
				else
				{
					point[1] = cur;
					pos[1] = Position( point[1] );
					vers++;
				}
			}
			else if( vers == 2 )
			{
				if( cur == point[0] | cur == point[1] )
				{
					Warning();
					if( novice_flag == ON )
						Message( "切断する平面を指定してください\n"
							+"Ｃキーを押すと切断面を確認できます" );
				}
				else
				{
					point[2] = cur;
					pos[2] = Position( point[2] );
					break;
				}
			}
		}
		else if( key == ESC | quit_flag == TRUE )
		{
			PopandClear( OVERWRITE );
			return FALSE;
		}
		else if ( key == BS )
		{
			if ( vers == 1 )
			{
				PopandClear( OVERWRITE );
				return FALSE;
			}
			else
			{
				if( cur != point[1] )
				{
					DrawEdge(edge);
					DrawLine( pick, point[0] );
					DrawLine( cur, point[1] );
					cur = point[1];
					vers --;
					DrawLine( cur, point[0] );
					Cursor( cur );
				}
				else
					vers --;
				edge = Edge();
			}
		}
		else if( key == 'c' )
			ModeChange();
		else
			temp = KeyProcess( key );
		if( ((key!=0 ) & (key != INPUT_KEY))
			| ( pick != Cursor())
			| (change_flag == ON ))
		{
			draw_flag = ON;
			edge_temp = edge;
			if( vers == 2 )
			{
				if((( pick != cur ) & (draw_mode == ON ))
				 | (( change_flag == ON ) & ( draw_mode == ON )))
				{
					if((cur != point[0]) & (cur != point[1]))
					{
						pos[2] = Position( cur );
						edge = ZanteEdge(work_sel, pos);
					}
					else
						edge = Edge();
				}
			}
			if(( draw_mode == ON ) & ( vers == 2 ))
				DrawEdge(edge_temp);
			DrawLine( pick, point[vers-1] );
		}
		else
			draw_flag = OFF;
		change_flag = OFF;
		pick = Cursor();
		input_flag = OFF;
	}
	Clear( OVERWRITE );
	Select( work_sel );
	for( i = 0; i< 2;i++)
	{
		for( j = 0; j< MAXOBJECT;j++ )
		{
			temp = org_obj_num+substr("0"+tostring(j),2);
			k = ObjSearch( temp );
			if( k < 0 )
				break;
		}
		k = ObjCurrent();
		if(( EXPERT == TRUE ) | ( MACHINE != "WINDOWS" ))
			obj_num[i] = ObjAppend( temp, ObjFile( k ));
		else
			obj_num[i] = ObjAppend( temp, MakeFile( temp, "suf" ));
	}
	ZantePolygons( work_sel, pos, obj_num[0], obj_num[1] );
	SelectObj( obj_num[0], TRUE, SELECT_OR );
	SelectObj( obj_num[1], TRUE, SELECT_OR );
	PolyDelete( work_sel );
	work_sel = Select();
	i = 0;
	while( Objects() > i )
	{
		temp = substr( ObjName( i ), (!org_obj_num));
		if( temp != org_obj_num )
			i++;
		else
		{
			SelectObj( i, TRUE, SELECT_UPDATE );
			if( SelectPolygons() == 0 )
				ObjDelete( i );
			else
				i++;
		}
	}
	Select( work_sel );
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
	Update( CLEAR );
	UpdateObject();
	return TRUE;
}
